﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System.Collections.Generic;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System;
namespace DNA.Mvc.Installation
{
    public static class InstallationHelpers
    {
        public static int WidgetsSeed(this IDataContext dbContext)
        {
            var _tmpls = dbContext.WidgetTemplates.All();
            foreach (var _tmpl in _tmpls)
                dbContext.WidgetDescriptors.Create(_tmpl, _tmpl.ID);
            return dbContext.SaveChanges();
        }

        private static IDictionary<string, object> ConvertObject(object data)
        {
            if (data is IDictionary<string, object>)
                return data as IDictionary<string, object>;

            var attr = BindingFlags.Public | BindingFlags.Instance;
            var dict = new Dictionary<string, object>();
            foreach (var property in data.GetType().GetProperties(attr))
            {
                if (property.CanRead)
                {
                    dict.Add(property.Name, property.GetValue(data, null));
                }
            }
            return dict;
        }

        public static Web Install(HttpContextBase httpContext, string solution)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");

            if (string.IsNullOrEmpty(solution))
                throw new ArgumentNullException("solution");

            if (!httpContext.Request.IsAuthenticated)
                throw new UnauthorizedAccessException();

            var userName = httpContext.User.Identity.Name;
            return Install(httpContext, solution, userName, userName);
        }

        public static Web Install(HttpContextBase httpContext, string solution, string name, string title, string desc = "", string theme = "default", WebTypes type = WebTypes.Personal)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");

            if (string.IsNullOrEmpty(solution))
                throw new ArgumentNullException("solution");

            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            if (!httpContext.Request.IsAuthenticated)
                throw new UnauthorizedAccessException();

            return Install(new Web()
            {
                Name = name,
                Type = (int)type,
                Title = string.IsNullOrEmpty(title) ? name : title,
                Description = desc,
                Theme = theme
            }, solution, type, httpContext);
        }

        public static Web Install(Web web, string solution, WebTypes type, HttpContextBase httpContext)
        {
            IDataContext dbContext = DependencyResolver.Current.GetService<IDataContext>();

            if (dbContext.Webs.GetByName(web.Name) != null)
                throw new Exception(string.Format("The {0} web is exists", web.Name));

            web.Type = (int)type;
            var _vals = ConvertObject(web);
            var settings = new Dictionary<string, object>();

            foreach (var key in _vals.Keys)
                settings.Add("Web." + key, _vals[key]);
            settings.Add("AppPath", httpContext.Server.MapPath("~/"));

            var _service = new InstallationService();
            var package = dbContext.Solutions.Find(p => p.Name.Equals(solution, StringComparison.OrdinalIgnoreCase));
            var filename = System.IO.Path.GetDirectoryName(httpContext.Server.MapPath(package.Url)) + "\\install.xml";
            _service.Install(filename, httpContext, settings);
            var newWeb = dbContext.Webs.GetByName(web.Name);

            if (newWeb != null && newWeb.Type != (int)type)
            {
                newWeb.Type = (int)type;
                dbContext.SaveChanges();
            }
            return newWeb;
        }
    }
}
